﻿// ********************************** 
// Densen Informatica 中讯科技 
// 作者：Alex Chow
// e-mail:zhouchuanglin@gmail.com 
// **********************************

using System.Collections.Generic;
using System.Reflection;


namespace System.Linq.Expressions;

public static partial class LambadaExpression
{            /// <summary>
             /// 创建lambda表达式：p=>true
             /// </summary>
             /// <typeparam name="T"></typeparam>
             /// <returns></returns>
    public static Expression<Func<T, bool>> True<T>()
    {
        return p => true;
    }

    /// <summary>
    /// 创建lambda表达式：p=>false
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public static Expression<Func<T, bool>> False<T>()
    {
        return p => false;
    }

    /// <summary>
    /// 创建lambda表达式：p=>p.propertyName
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <typeparam name="TKey"></typeparam>
    /// <param name="propertyName"></param>
    /// <returns></returns>
    public static Expression<Func<T, TKey>> GetOrderExpression<T, TKey>(string propertyName)
    {
        ParameterExpression parameter = Expression.Parameter(typeof(T), "p");
        return Expression.Lambda<Func<T, TKey>>(Expression.Property(parameter, propertyName), parameter);
    }
    /// <summary>
    /// 创建lambda表达式：p=>p.propertyName == propertyValue
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="propertyName"></param>
    /// <param name="propertyValue"></param>
    /// <returns></returns>
    public static Expression<Func<T, bool>> CreateEqual<T>(string propertyName, string propertyValue)
    {
        ParameterExpression parameter = Expression.Parameter(typeof(T), "p");//创建参数p
        MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
        ConstantExpression constant = Expression.Constant(propertyValue);//创建常数
        return Expression.Lambda<Func<T, bool>>(Expression.Equal(member, constant), parameter);
    }

    /// <summary>
    /// 创建lambda表达式：p=>p.propertyName != propertyValue
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="propertyName"></param>
    /// <param name="propertyValue"></param>
    /// <returns></returns>
    public static Expression<Func<T, bool>> CreateNotEqual<T>(string propertyName, string propertyValue)
    {
        ParameterExpression parameter = Expression.Parameter(typeof(T), "p");//创建参数p
        MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
        ConstantExpression constant = Expression.Constant(propertyValue);//创建常数
        return Expression.Lambda<Func<T, bool>>(Expression.NotEqual(member, constant), parameter);
    }

    /// <summary>
    /// 创建lambda表达式：p=>p.propertyName > propertyValue
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="propertyName"></param>
    /// <param name="propertyValue"></param>
    /// <returns></returns>
    public static Expression<Func<T, bool>> CreateGreaterThan<T>(string propertyName, string propertyValue)
    {
        ParameterExpression parameter = Expression.Parameter(typeof(T), "p");//创建参数p
        MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
        ConstantExpression constant = Expression.Constant(propertyValue);//创建常数
        return Expression.Lambda<Func<T, bool>>(Expression.GreaterThan(member, constant), parameter);
    }

    /// <summary>
    /// 创建lambda表达式：p=>p.propertyName [ propertyValue]
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="propertyName"></param>
    /// <param name="propertyValue"></param>
    /// <returns></returns>
    public static Expression<Func<T, bool>> CreateLessThan<T>(string propertyName, string propertyValue)
    {
        ParameterExpression parameter = Expression.Parameter(typeof(T), "p");//创建参数p
        MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
        ConstantExpression constant = Expression.Constant(propertyValue);//创建常数
        return Expression.Lambda<Func<T, bool>>(Expression.LessThan(member, constant), parameter);
    }

    /// <summary>
    /// 创建lambda表达式：p=>p.propertyName >= propertyValue
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="propertyName"></param>
    /// <param name="propertyValue"></param>
    /// <returns></returns>
    public static Expression<Func<T, bool>> CreateGreaterThanOrEqual<T>(string propertyName, string propertyValue)
    {
        ParameterExpression parameter = Expression.Parameter(typeof(T), "p");//创建参数p
        MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
        ConstantExpression constant = Expression.Constant(propertyValue);//创建常数
        return Expression.Lambda<Func<T, bool>>(Expression.GreaterThanOrEqual(member, constant), parameter);
    }

    /// <summary>
    /// 创建lambda表达式：p=>p.propertyName = propertyValue
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="propertyName"></param>
    /// <param name="propertyValue"></param>
    /// <returns></returns>
    public static Expression<Func<T, bool>> CreateLessThanOrEqual<T>(string propertyName, string propertyValue)
    {
        ParameterExpression parameter = Expression.Parameter(typeof(T), "p");//创建参数p
        MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
        ConstantExpression constant = Expression.Constant(propertyValue);//创建常数
        return Expression.Lambda<Func<T, bool>>(Expression.LessThanOrEqual(member, constant), parameter);
    }

    /// <summary>
    /// 创建lambda表达式：p=>p.propertyName.Contains(propertyValue)
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="propertyName"></param>
    /// <param name="propertyValue"></param>
    /// <returns></returns>
    public static Expression<Func<T, bool>> GetContains<T>(string propertyName, string propertyValue)
    {
        ParameterExpression parameter = Expression.Parameter(typeof(T), "p");
        MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
        MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
        ConstantExpression constant = Expression.Constant(propertyValue, typeof(string));
        return Expression.Lambda<Func<T, bool>>(Expression.Call(member, method, constant), parameter);
    }

    /// <summary>
    /// 创建lambda表达式：!(p=>p.propertyName.Contains(propertyValue))
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="propertyName"></param>
    /// <param name="propertyValue"></param>
    /// <returns></returns>
    public static Expression<Func<T, bool>> GetNotContains<T>(string propertyName, string propertyValue)
    {
        ParameterExpression parameter = Expression.Parameter(typeof(T), "p");
        MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
        MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
        ConstantExpression constant = Expression.Constant(propertyValue, typeof(string));
        return Expression.Lambda<Func<T, bool>>(Expression.Not(Expression.Call(member, method, constant)), parameter);
    }



#if NETSTANDARD2_0
    public static IEnumerable<T> SkipLast<T>(this IEnumerable<T> source, int count)
    {
        return source.TakeWhile((item, index) => index < source.Count() - count);
    }
#endif
}

